﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace TfCmsClient
{
    public class TabsToolStripRenderer : ToolStripRenderer
    {
        private Rectangle GetParentRectangle(ToolStrip ts)
        {
            var result = ts.TopLevelControl.ClientRectangle;
            result.Width -= 1;
            result.Height -= 1;
            //result.X += 1;
            //result.Y += 1;
            return result;
        }

        private static bool MouseIsOver(Control c)
        {
            Rectangle r = c.RectangleToScreen(c.ClientRectangle);
            return r.Contains(Control.MousePosition);
        }

        private bool MouseIsOver(ToolStripItem c)
        {
            Rectangle r = c.Owner.RectangleToScreen(c.Bounds);
            return r.Contains(Control.MousePosition);
        }

        private Rectangle CenterRectangle(Rectangle a, Size b)
        {
            return new Rectangle(
                a.Left + (a.Width - b.Width) / 2,
                a.Top + (a.Height - b.Height) / 2,
                b.Width, b.Height);
        }

        protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
        {
            Rectangle r = GetParentRectangle(e.ToolStrip);
            using (var brush = new LinearGradientBrush(r, SystemColors.InactiveCaption, SystemColors.GradientInactiveCaption, LinearGradientMode.Horizontal))
            {
                e.Graphics.FillRectangle(brush, e.ToolStrip.ClientRectangle);
            }
        }

        protected override void InitializeItem(ToolStripItem item)
        {
            if (item.AutoSize)
            {
                item.AutoSize = false;
                if (item is ToolStripButton)
                {
                    item.Width += 32;
                }
                else if (item is ToolStripDropDownButton)
                {
                    item.Width += 16;
                }
            }
            base.InitializeItem(item);
        }

        protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
        {
            Rectangle r = e.ToolStrip.ClientRectangle;
            r.Height -= 1;
            r.Width -= 1;
            e.Graphics.DrawLine(SystemPens.InactiveCaption, r.Left, r.Bottom, r.Right, r.Bottom);
        }

        protected override void OnRenderDropDownButtonBackground(ToolStripItemRenderEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            if (MouseIsOver(e.Item))
            {
                Rectangle r = e.Item.ContentRectangle;
                using (var brush = new LinearGradientBrush(r, Color.FromArgb(200, SystemColors.ActiveCaption), Color.FromArgb(0, SystemColors.GradientActiveCaption), LinearGradientMode.Vertical))
                {
                    using (var path = RoundedRectangle.Create(r, 5))
                    {
                        e.Graphics.FillPath(brush, path);
                    }
                }
            }
        }

        protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            Rectangle r = e.ArrowRectangle;

            if (r.Width > r.Height)
            {
                r.X = (r.Height - r.Width) / 2;
                r.Width = r.Height;
            }
            else
            {
                r.Y = (r.Height - r.Width) / 2;
                r.Height = r.Width;
            }

            using (var path = new GraphicsPath())
            {
                switch (e.Direction)
                {
                    case ArrowDirection.Down:
                        path.AddLine(r.Left, r.Top, r.Left + r.Width / 2f, r.Bottom);
                        path.AddLine(r.Left + r.Width / 2f, r.Bottom, r.Right, r.Top);
                        break;
                    case ArrowDirection.Left:
                        path.AddLine(r.Right, r.Top, r.Left, r.Top + r.Height / 2f);
                        path.AddLine(r.Left, r.Top + r.Height / 2f, r.Right, r.Bottom);
                        break;
                    case ArrowDirection.Right:
                        path.AddLine(r.Left, r.Top, r.Right, r.Top + r.Height / 2f);
                        path.AddLine(r.Right, r.Top + r.Height / 2f, r.Left, r.Bottom);
                        break;
                    case ArrowDirection.Up:
                        path.AddLine(r.Left, r.Bottom, r.Left + r.Width / 2f, r.Top);
                        path.AddLine(r.Left + r.Width / 2f, r.Top, r.Right, r.Bottom);
                        break;
                }

                using (var brush = new LinearGradientBrush(r, Color.FromArgb(200, SystemColors.ActiveCaption), Color.FromArgb(0, SystemColors.GradientActiveCaption), LinearGradientMode.Vertical))
                {
                    e.Graphics.FillPath(brush, path);
                }
            }
        }

        protected override void OnRenderItemImage(ToolStripItemImageRenderEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            Rectangle r = CenterRectangle(e.ImageRectangle, e.Image.Size);
            if (e.Item is ToolStripButton)
            {
                r.X += 10;
            }
            e.Graphics.DrawImage(e.Image, r);
        }

        protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            Rectangle r = e.TextRectangle;
            var brush = SystemBrushes.InactiveCaptionText;
            if (e.Item is ToolStripButton)
            {
                r.X += 12;
                if (((ToolStripButton) e.Item).Checked)
                {
                    brush = SystemBrushes.ActiveCaptionText;
                }
            }
            if (MouseIsOver(e.Item))
            {
                brush = Brushes.White;
            }
            StringFormat sf = new StringFormat();
            sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide;
            
            r.X += 1;
            r.Y += 1;
            using (var newBrush = new SolidBrush(Color.FromArgb(128, Color.Black)))
                e.Graphics.DrawString(e.Text, e.TextFont, newBrush, r, sf);
            r.X -= 1;
            r.Y -= 1;
            e.Graphics.DrawString(e.Text, e.TextFont, brush, r, sf);
            
        }

        protected override void OnRenderButtonBackground(ToolStripItemRenderEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            Rectangle r = e.Item.ContentRectangle;
            r.Height += r.Y;
            r.Y = 0;

            using (var path = new GraphicsPath())
            {
                path.AddArc(r.Left, r.Top, 10, 10, 270, 90);
                path.AddLine(r.Left + 10, r.Top + 10, r.Left + 10, r.Bottom - 10);
                path.AddArc(r.Left + 10, r.Bottom - 10, 10, 10, 180, -90);
                path.AddLine(r.Left + 20, r.Bottom, r.Right - 10, r.Bottom);
                path.AddArc(r.Right - 10, r.Bottom - 10, 10, 10, 90, -90);

                using (var fillPath = (GraphicsPath) path.Clone())
                {
                    fillPath.AddLine(r.Right, r.Bottom - 10, r.Right, r.Top);
                    fillPath.AddLine(r.Right, r.Top, r.Left, r.Top);

                    var opacity = MouseIsOver(e.Item) ? 127 : 10;
                    Rectangle r2 = new Rectangle(r.Left, r.Top, r.Width + 5, r.Height);
                    if (e.Item is ToolStripButton && ((ToolStripButton) e.Item).Checked)
                    {
                        opacity += 128;
                    }
                    using (var brush = new LinearGradientBrush(r2, Color.FromArgb(opacity, SystemColors.ActiveCaption), Color.FromArgb(0, SystemColors.GradientActiveCaption), LinearGradientMode.Horizontal))
                    {
                        e.Graphics.FillPath(brush, fillPath);
                    }
                    using (var brush = new LinearGradientBrush(r2, Color.FromArgb(200, SystemColors.ActiveCaption), Color.FromArgb(0, SystemColors.GradientActiveCaption), LinearGradientMode.Horizontal))
                    {
                        using (var pen = new Pen(brush))
                        {
                            e.Graphics.DrawPath(pen, path);
                        }
                    }
                }
            }
        }

    }

    public abstract class RoundedRectangle
    {
        public enum RectangleCorners
        {
            None = 0,
            TopLeft = 1,
            TopRight = 2,
            BottomLeft = 4,
            BottomRight = 8,
            All = TopLeft | TopRight | BottomLeft | BottomRight
        }

        public static GraphicsPath Create(int x, int y, int width, int height,
                                          int radius, RectangleCorners corners)
        {
            int xw = x + width;
            int yh = y + height;
            int xwr = xw - radius;
            int yhr = yh - radius;
            int xr = x + radius;
            int yr = y + radius;
            int r2 = radius * 2;
            int xwr2 = xw - r2;
            int yhr2 = yh - r2;

            GraphicsPath p = new GraphicsPath();
            p.StartFigure();

            //Top Left Corner
            if ((RectangleCorners.TopLeft & corners) == RectangleCorners.TopLeft)
            {
                p.AddArc(x, y, r2, r2, 180, 90);
            }
            else
            {
                p.AddLine(x, yr, x, y);
                p.AddLine(x, y, xr, y);
            }

            //Top Edge
            p.AddLine(xr, y, xwr, y);

            //Top Right Corner
            if ((RectangleCorners.TopRight & corners) == RectangleCorners.TopRight)
            {
                p.AddArc(xwr2, y, r2, r2, 270, 90);
            }
            else
            {
                p.AddLine(xwr, y, xw, y);
                p.AddLine(xw, y, xw, yr);
            }

            //Right Edge
            p.AddLine(xw, yr, xw, yhr);

            //Bottom Right Corner
            if ((RectangleCorners.BottomRight & corners) == RectangleCorners.BottomRight)
            {
                p.AddArc(xwr2, yhr2, r2, r2, 0, 90);
            }
            else
            {
                p.AddLine(xw, yhr, xw, yh);
                p.AddLine(xw, yh, xwr, yh);
            }

            //Bottom Edge
            p.AddLine(xwr, yh, xr, yh);

            //Bottom Left Corner
            if ((RectangleCorners.BottomLeft & corners) == RectangleCorners.BottomLeft)
            {
                p.AddArc(x, yhr2, r2, r2, 90, 90);
            }
            else
            {
                p.AddLine(xr, yh, x, yh);
                p.AddLine(x, yh, x, yhr);
            }

            //Left Edge
            p.AddLine(x, yhr, x, yr);

            p.CloseFigure();
            return p;
        }

        public static GraphicsPath Create(Rectangle rect, int radius, RectangleCorners c)
        {
            return Create(rect.X, rect.Y, rect.Width, rect.Height, radius, c);
        }

        public static GraphicsPath Create(int x, int y, int width, int height, int radius)
        {
            return Create(x, y, width, height, radius, RectangleCorners.All);
        }

        public static GraphicsPath Create(Rectangle rect, int radius)
        {
            return Create(rect.X, rect.Y, rect.Width, rect.Height, radius);
        }

        public static GraphicsPath Create(int x, int y, int width, int height)
        {
            return Create(x, y, width, height, 5);
        }

        public static GraphicsPath Create(Rectangle rect)
        {
            return Create(rect.X, rect.Y, rect.Width, rect.Height);
        }
    }
}
